#include <func.h>

#define NUM 10000000

int main()
{
    // 共享内存申请
    int shmid;
    shmid = shmget(1000,4096,IPC_CREAT|0600);//第一次创建，第二次相同的key值是获取
    ERROR_CHECK(shmid,-1,"shmget");
    printf("shmid=%d\n",shmid);
    int *p = shmat(shmid,NULL,0);//共享内存连接到本进程内
    ERROR_CHECK(p,(char*)-1,"shmat");

    // 信号量申请
    int semid = semget(1000, 1, IPC_CREAT|0600); // 设置一个信号量
    ERROR_CHECK(semid, -1, "semget");
    int ret = semctl(semid, 0, SETVAL, 1); // 给这个信号量赋初值
    ERROR_CHECK(semid, -1, "semctl");
    
    // 记录时间
    time_t start, end;
    start = time(NULL);
    if(!fork())
    {
        struct sembuf P, V;
        P.sem_num = 0; // 信号量的编号
        P.sem_op = -1; // 信号量的操作
        P.sem_flg = SEM_UNDO; // 信号量被杀死后要执行什么操作
        V.sem_num = 0;
        V.sem_op = +1;
        V.sem_flg = SEM_UNDO;

        for (int i = 0; i < NUM; i ++) 
        {
            semop(semid, &P, 1); // 访问临界资源前加锁
            (*p) ++;
            semop(semid, &V, 1); // 解锁
        }
        // printf("I am child %s\n",p);
    }else{
        // strcpy(p,"hello");

        struct sembuf P, V;
        P.sem_num = 0; // 信号量的编号
        P.sem_op = -1; // 信号量的操作
        P.sem_flg = SEM_UNDO; // 信号量被杀死后要执行什么操作
        V.sem_num = 0;
        V.sem_op = +1;
        V.sem_flg = SEM_UNDO;

        for (int i = 0; i < NUM; i ++)
        {
            semop(semid, &P, 1);
            (*p) ++;
            semop(semid, &V, 1);
        } 
        wait(NULL);
        end = time(NULL);
        printf("%d\n", *p);
        printf("用时：%lds\n", end - start);
    }
    
    // 断开共享内存链接
    shmdt(p);
    // 删除共享内存
    shmctl(shmid, IPC_RMID, NULL);
    return 0;
}